#ifndef _CORE_EXCEPTION_H_
#define _CORE_EXCEPTION_H_

#include <setjmp.h>
#include <stdint.h>

#define exceptionBegin()   setjmp(exceptionNewFrame()->jmpBuf)


typedef struct ExceptionFrame ExceptionFrame;


/**
 * The different try/catch/finally blocks of an exception-handling statement
 */
typedef enum ExceptionBlock
{
  ExceptionBlock_Try,
  ExceptionBlock_Catch,
  ExceptionBlock_Finally
} ExceptionBlock;


/**
 * Contains all the informations necessary to restore the previous state when exceptionThrow() is called
 */
struct ExceptionFrame
{
  jmp_buf jmpBuf;
  void* exception;
  ExceptionFrame* prevFrame;
  uint8_t block;
  uint8_t state;
};


ExceptionFrame* exceptionNewFrame(void);
void            exceptionThrow(void* exception);
void*           exceptionPeek(void);
void*           exceptionCatch(void);
void            exceptionEnd(void);


#endif
